/**
 * Copyright (c) 2015-2030 by Beijing Yanlight Co., Ltd.
 * All rights reserved.
 */
package com.yanlight.app.controller;

import com.yanlight.Constants;
import com.yanlight.app.request.OrderPlaceRequest;
import com.yanlight.app.request.OrderPrePayRequest;
import com.yanlight.app.request.OrderUnifiedPlaceRequest;
import com.yanlight.app.response.OrderPrePayResponse;
import com.yanlight.app.response.PaycodeVerifyResponse;
import com.yanlight.app.service.AdCountService;
import com.yanlight.app.service.OrderService;
import com.yanlight.app.service.PaycodeService;
import com.yanlight.exception.ErrorType;
import com.yanlight.exception.TradeException;
import com.yanlight.support.http.Response;
import com.yanlight.support.pay.PayNotifyHandler;
import com.yanlight.support.pay.PayNotifyHandlerFactory;
import com.yanlight.type.PayType;
import com.yanlight.util.CookieUtil;
import com.yanlight.util.ResponseUtil;
import com.yanlight.util.WebUtil;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author haolw
 * @time 2017/10/28
 */
@RestController
@RequestMapping("/order")
public class OrderController extends BaseController {
    @Autowired
    private OrderService orderService;
    @Autowired
    private PaycodeService paycodeService;

    @Autowired
    private AdCountService adCountService;

    /**
     * 线下聚合码统一支付
     *
     * @param httpRequest
     * @param request
     * @param paycode
     * @return
     */
    @PostMapping("/place/{paycode}")
    public Response place(HttpServletRequest httpRequest, OrderPlaceRequest request, @PathVariable String paycode) {
        PaycodeVerifyResponse paycodeResponse = paycodeService.verify(paycode);
        Integer companyId = paycodeResponse.getCompanyId();
        Integer binderId = paycodeResponse.getBinderId();
        Integer payCodeId = paycodeResponse.getId();
        Integer payType = request.getPayType();
        String totalFee = request.getTotalFee();
        if (!NumberUtils.isParsable(totalFee)) {
            throw TradeException.error(ErrorType.INVALID_FEE);
        }

        String buyerId = null;
        if (PayType.ALIPAY.getType().equals(payType)) {
            buyerId = CookieUtil.getValue(httpRequest, Constants.ALIPAY_USER_ID);
        } else if (PayType.WXPAY.getType().equals(payType)) {
            buyerId = CookieUtil.getValue(httpRequest, Constants.WX_OPENID);
            request.setSpbillCreateIp(WebUtil.getTerminalIp(httpRequest));
        }
        request.setBuyerId(buyerId);
        request.setCompanyId(companyId);
        request.setPayCodeId(payCodeId);
        request.setOperationId(binderId);
        return ResponseUtil.success(orderService.place(request));
    }

    /**
     * 开发者统一下单
     *
     * @param request
     * @return
     */
    @PostMapping("/unifiedPlace")
    public Response unifiedPlace(HttpServletRequest httpRequest, OrderUnifiedPlaceRequest request) {
        request.setCompanyId(getDevBindCompanyId());
        request.setOperationId(getDevId());
        return ResponseUtil.success(orderService.unifiedPlace(request));
    }

    /**
     * 开发者回调支付页面
     *
     * @param httpRequest
     * @param model
     * @param outTradeNo
     * @return
     */
    @GetMapping("/pay/{outTradeNo}")
    public ModelAndView pay(HttpServletRequest httpRequest, ModelAndView model, @PathVariable String outTradeNo) {
        OrderPrePayRequest request = new OrderPrePayRequest();
        String viewName = "order/pay";
        Integer payType = null;
        String buyerId = null;
        if (WebUtil.isWxBrowse(httpRequest)) {
            payType = PayType.WXPAY.getType();
            buyerId = CookieUtil.getValue(httpRequest, Constants.WX_OPENID);
            request.setSpbillCreateIp(WebUtil.getTerminalIp(httpRequest));
        } else if (WebUtil.isAlipayBrowse(httpRequest)) {
            payType = PayType.ALIPAY.getType();
            buyerId = CookieUtil.getValue(httpRequest, Constants.ALIPAY_USER_ID);
        } else {
            model.setViewName("noWayPay");
            return model;
        }
        request.setOutTradeNo(outTradeNo);
        request.setBuyerId(buyerId);
        request.setPayType(payType);
        OrderPrePayResponse payResponse = orderService.prePay(request);
        model.addObject("result", payResponse);
        model.setViewName(viewName);
        return model;
    }

    /**
     * 微信、支付宝支付加过通知
     *
     * @param request
     * @param response
     * @param companyId
     * @param payType
     */
    @RequestMapping("/notifyPay/{companyId}/{payType}")
    public void notifyWxPay(HttpServletRequest request, HttpServletResponse response, @PathVariable Integer companyId,
                            @PathVariable Integer payType) {

        String packets = WebUtil.getRequestPackets(request);
        PayNotifyHandler notifyHandler = PayNotifyHandlerFactory.getPayNotifyHandler(payType);
        notifyHandler.handPayNotify(packets, response, orderService);

        adCountService.firstPayIncrease(packets, companyId.longValue(), payType);
    }

}
